#################################################1.服务器端用redis存储购物车信息######################################################
import base64
import pickle

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
# Create your views here.
from goods.models import SKU
from .serializers_redis import CartSerializer, CartSKUSerializer
from django_redis import get_redis_connection

class CartsView(APIView):

    def perform_authentication(self, request):
        pass


    def post(self,request):

        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        sku_id = serializer.data.get('sku_id')
        count = serializer.data.get('count')
        selected = serializer.data.get('selected')


        try:
            user = request.user
        except Exception:
            user = None

        if not user:
            #用户未登录，设置cookie

            cart_cookie = request.COOKIES.get('cart')
            if not cart_cookie:
                #当前无cookie信息
                cart_plain = {}
            else:
                #有cookie信息
                cart_plain = pickle.loads(base64.b64decode(cart_cookie.encode()))

            cart_plain[sku_id]={
                'count':count,
                'selected':selected
            }
            cart_cipher = base64.b64encode(pickle.dumps(cart_plain)).decode()
            response = Response(serializer.data)
            response.set_cookie('cart',cart_cipher)
            return response
        else:
            #用户已登录，设置redis
            redis = get_redis_connection('cart')
            redis.hset('cart_%s'%user.id,sku_id,count)
            if selected:
                redis.sadd('cart_selected_%s'%user.id,sku_id)
            else:
                redis.srem('cart_selected_%s'%user.id,sku_id)
            return Response(serializer.data)


    def get(self,request):

        try:
            user = request.user
        except Exception:
            user =None

        cart_plain={ }
        if not user:
            #用户未登录，从cookie拿数据
            cart_cookie = request.COOKIES.get('cart')
            if not cart_cookie:
                cart_plain = {}
            else:
                cart_plain = pickle.loads(base64.b64decode(cart_cookie.encode()))

        else:
            #用户已登录，从redis中拿数据
            redis = get_redis_connection('cart')

            cart_redis = redis.hgetall('cart_%s'%user.id)
            cart_selected = redis.smembers('cart_selected_%s'%user.id)

            for sku_id,sku_count in cart_redis.items():
                cart_plain[int(sku_id)] ={
                    'count':sku_count,
                    'selected':sku_id in cart_selected
                }


        sku_ids = cart_plain.keys()
        skus = SKU.objects.filter(pk__in=sku_ids)
        for sku in skus:
            sku.count = cart_plain[sku.id]['count']
            sku.selected = cart_plain[sku.id]['selected']
        serializer = CartSKUSerializer(skus, many=True)

        return Response(serializer.data)


    def put(self,request):

        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.data.get('sku_id')
        count = serializer.data.get('count')
        selected = serializer.data.get('selected')

        try:
            user = request.user
        except Exception:
            user = None

        if not user:
            #用户未登录，更新cookie数据
            cart_cookie = request.COOKIES.get('cart')
            if not cart_cookie:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            else:
                cart_plain = pickle.loads(base64.b64decode(cart_cookie.encode()))

            cart_plain[sku_id]={
                'count':count,
                'selected':selected
            }
            cart_cipher = base64.b64encode(pickle.dumps(cart_plain)).decode()
            response = Response(serializer.data)
            response.set_cookie('cart',cart_cipher)
            return response


        else:
            #用户已登录，更新redis数据
            redis = get_redis_connection('cart')

            if not redis:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            else:
                redis.hset('cart_%s'%user.id,sku_id,count)
                if selected:
                    redis.sadd('cart_selected_%s'%user.id,sku_id)
                else:
                    redis.srem('cart_selected_%s'%user.id,sku_id)

                return Response(serializer.data)


    def delete(self,request):

        sku_id = request.data.get('sku_id')
        try:
            SKU.objects.get(pk=sku_id)
        except SKU.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        try:
            user = request.user
        except Exception:
            user = None
        if user is not None and user.is_authenticated:
            #用户已登录，从redis中删除数据
            redis = get_redis_connection('cart')
            if not redis:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            else:
                #1.直接操作数据库，增加了数据库的交互载荷
                # redis.hdel('cart_%s'%user.id,sku_id)
                # redis.srem('cart_selected_%s'%user.id,sku_id)
                #2.通过redis的管道可以先收集所有的数据库操作，然后统一执行。
                pl=redis.pipeline()
                pl.hdel('cart_%s'%user.id,sku_id)
                pl.srem('cart_selected_%s'%user.id,sku_id)
                pl.execute()

                return Response(request.data)
        else:
            #用户未登录，从cookie删除数据
            cart_cookie = request.COOKIES.get('cart')
            if not cart_cookie:
                return Response(status=status.HTTP_400_BAD_REQUEST)
            else:
                cart_plain = pickle.loads(base64.b64decode(cart_cookie.encode()))

                try:
                    del cart_plain[sku_id]
                except Exception:
                    return Response(status=status.HTTP_400_BAD_REQUEST)

                cart_cipher = base64.b64encode(pickle.dumps(cart_plain)).decode()
                response = Response(request.data)
                response.set_cookie('cart',cart_cipher)

                return response




